package com.proxy.parser.visitor;

import com.alibaba.druid.sql.ast.SQLLimit;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.proxy.common.model.ProxyTable;
import com.proxy.parser.ParsedResult;
import com.proxy.parser.result.SelectResult;
import com.proxy.parser.PoxyVisitor;

import java.util.*;

/**
 * Created by liufish on 16/12/5.
 */
public class SelectVisitor extends MySqlSchemaStatVisitor implements PoxyVisitor {

    private SelectResult selectParsedResult;


    public SelectVisitor(ParsedResult parsedResult){
        this.selectParsedResult = (SelectResult)parsedResult;
    }

    /**
     * 查询解析过滤开始
     */
    @Override
    public boolean visit(MySqlSelectQueryBlock x) {
        boolean superValue = super.visit(x);
        return superValue;
    }

    /**
     * 查询解析过滤结束
     */
    @Override
    public void endVisit(MySqlSelectQueryBlock x) {

        System.out.println("-----");

        // select SQLPropertyExpr
        super.endVisit(x);

        x.getSelectList();

        // SQLJoinTableSource   left SQLExprTableSource right SQLJoinTableSources
        x.getFrom();

        //SQLBinaryOpExpr
        x.getWhere();

      /*
      Map<String ,String []> tableMap = new HashMap<>();

        SQLTableSource fromSource = x.getFrom();

        //单表
        if(fromSource instanceof SQLExprTableSource ){
            SQLExprTableSource from = (SQLExprTableSource) fromSource;

            SQLPropertyExpr expr =  (SQLPropertyExpr)from.getExpr();

            SQLIdentifierExpr owner = (SQLIdentifierExpr)expr.getOwner();
            String db = owner.getName();
            String alias =  from.getAlias();
            String tableName = expr.getName();
            tableMap.put(tableName,new String[]{tableName,alias,db});
        }


        if(fromSource instanceof SQLJoinTableSource){
            SQLJoinTableSource joinTableSource = (SQLJoinTableSource)fromSource;
            SQLExprTableSource leftExpr =  (SQLExprTableSource)joinTableSource.getLeft();


            if(joinTableSource.getRight() instanceof SQLExprTableSource ){
                SQLExprTableSource rightExpr =  (SQLExprTableSource)joinTableSource.getRight();
            }
            if(joinTableSource.getRight() instanceof SQLJoinTableSource){
                SQLJoinTableSource rightJoin  = (SQLJoinTableSource) joinTableSource.getRight();
            }

        }

        */





        //tables 获取sql语句的表名
        Map<String, ProxyTable> tables = this.selectParsedResult.getTables();
        for (Map.Entry<TableStat.Name, TableStat> entry : this.tableStats.entrySet()){
            ProxyTable table = new ProxyTable();
            table.setName(entry.getKey().getName());
            tables.put(entry.getKey().getName(),table);

          /*  String [] tableInfo =  tableMap.get(entry.getKey().getName());
            if(tableInfo != null){
                table.setAlias(tableInfo[1]);
                table.setDb(tableInfo[2]);
            }*/


        }
        //columns  字段名称
        Map<ProxyTable.Column, ProxyTable.Column> columns = this.selectParsedResult.getColumns();
        for (Map.Entry<TableStat.Column, TableStat.Column>  entry : this.columns.entrySet()){
            ProxyTable.Column column = new ProxyTable.Column();
            column.setColumnName(entry.getValue().getName());
            column.setTableName(entry.getValue().getTable());
            column.setGroupBy(entry.getValue().isGroupBy());
            column.setHaving(entry.getValue().isHaving());
            column.setJoin(entry.getValue().isJoin());
            column.setSelect(entry.getValue().isSelect());
            column.setWhere(entry.getValue().isWhere());
            columns.put(column,column);
        }

        //conditions 条件
        List<ProxyTable.Condition> conditions =  this.selectParsedResult.getConditions();
        for (TableStat.Condition item : this.conditions){
            ProxyTable.Condition condition = new ProxyTable.Condition();

            condition.setOperator(item.getOperator());
            condition.setValues(item.getValues());

            ProxyTable.Column column = new ProxyTable.Column();
            column.setColumnName(item.getColumn().getName());
            column.setTableName(item.getColumn().getTable());
            column.setGroupBy(item.getColumn().isGroupBy());
            column.setHaving(item.getColumn().isHaving());
            column.setJoin(item.getColumn().isJoin());
            column.setSelect(item.getColumn().isSelect());
            column.setWhere(item.getColumn().isWhere());

            condition.setColumn(column);
            conditions.add(condition);
        }

        //relationships 关系
        Set<ProxyTable.Relationship> relationships = this.selectParsedResult.getRelationships();

        for (TableStat.Relationship item : this.relationships){
            ProxyTable.Relationship relationship = new ProxyTable.Relationship();
            relationship.setOperator(item.getOperator());

            TableStat.Column left = item.getLeft();
            ProxyTable.Column leftColumn = new ProxyTable.Column();
            leftColumn.setColumnName(left.getName());
            leftColumn.setTableName(left.getTable());
            leftColumn.setGroupBy(left.isGroupBy());
            leftColumn.setHaving(left.isHaving());
            leftColumn.setJoin(left.isJoin());
            leftColumn.setSelect(left.isSelect());
            leftColumn.setWhere(left.isWhere());
            relationship.setLeft(leftColumn);

            TableStat.Column right = item.getRight();
            ProxyTable.Column rightColumn = new ProxyTable.Column();
            rightColumn.setColumnName(right.getName());
            rightColumn.setTableName(right.getTable());
            rightColumn.setGroupBy(right.isGroupBy());
            rightColumn.setHaving(right.isHaving());
            rightColumn.setJoin(right.isJoin());
            rightColumn.setSelect(right.isSelect());
            rightColumn.setWhere(right.isWhere());
            relationship.setRight(rightColumn);


            relationships.add(relationship);
        }

        //排序
        List<ProxyTable.Column> orderByColumns = this.selectParsedResult.getOrderByColumns();
        for (TableStat.Column item : this.orderByColumns){
            ProxyTable.Column column = new ProxyTable.Column();
            column.setColumnName(item.getName());
            column.setTableName(item.getTable());
            column.setGroupBy(item.isGroupBy());
            column.setHaving(item.isHaving());
            column.setJoin(item.isJoin());
            column.setSelect(item.isSelect());
            column.setWhere(item.isWhere());
            orderByColumns.add(column);
        }

        //分组
        Set<ProxyTable.Column> groupByColumns = this.selectParsedResult.getGroupByColumns();
        for (TableStat.Column item : this.groupByColumns){
            ProxyTable.Column column = new ProxyTable.Column();
            column.setGroupBy(item.isGroupBy());
            column.setHaving(item.isHaving());
            column.setJoin(item.isJoin());
            column.setSelect(item.isSelect());
            column.setWhere(item.isWhere());
            column.setColumnName(item.getName());
            column.setTableName(item.getTable());
            groupByColumns.add(column);
        }
        //当前表
        this.selectParsedResult.setCurrentTable(this.currentTable);

        //参数值
        this.selectParsedResult.getParameters().addAll(this.getParameters());

        //limit
        SQLLimit limit =  x.getLimit();
        if(limit != null ){
            int rowCount = 0;
            if(limit.getRowCount() instanceof SQLIntegerExpr){
                SQLIntegerExpr integerExpr = (SQLIntegerExpr)limit.getRowCount();
                rowCount = integerExpr.getNumber().intValue();
            }
            int offset = 0;
            if(limit.getOffset() instanceof SQLIntegerExpr){
                SQLIntegerExpr integerExpr = (SQLIntegerExpr)limit.getOffset();
                offset = integerExpr.getNumber().intValue();
            }
            if(rowCount != 0){
                ProxyTable.Limit proxyLimit = new ProxyTable.Limit();
                proxyLimit.setOffset(offset);
                proxyLimit.setRowCount(rowCount);
                this.selectParsedResult.setLimit(proxyLimit);
            }
        }
    }



}
